package org.budo.weixin.qiye.api;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.budo.support.http.client.HttpUtil;
import org.budo.support.http.client.Request;
import org.budo.support.http.client.Response;
import org.budo.support.lang.util.BooleanUtil;
import org.budo.support.lang.util.NumberUtil;
import org.budo.support.lang.util.StringUtil;
import org.budo.support.slf4j.Slf4j;
import org.budo.weixin.api.WeixinMediaUploadResult;
import org.budo.weixin.qiye.WeixinQiyeMessage;
import org.budo.weixin.qiye.util.WeixinQiyeMessageUtil;
import org.slf4j.Logger;

import com.alibaba.fastjson.JSON;

/**
 * @author li
 * @version 1 (2015年10月12日 下午2:21:25)
 * @since Java7
 */
public class WeixinQiyeApi implements Serializable {
    private static final long serialVersionUID = -3550803965327201545L;

    private Map<String, Integer> retryCount = new HashMap<String, Integer>();

    private static final Logger log = Slf4j.getLogger();

    private String accessToken;

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    /**
     * 获取微信Token
     */
    public String getWeixinToken(String corpId, String corpSecret) {
        Request request = new Request();
        request.setUrl("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpId + "&corpsecret=" + corpSecret);
        request.setMethod(Request.GET);
        Response response = request.execute();
        log.info("getWeixinToken, response=" + (null == response ? response : response.toSimpleString()));

        String result = response.getBody();
        Map<String, Object> map = JSON.parseObject(result);
        String token = StringUtil.toString(map.get("access_token"));
        if (StringUtil.isEmpty(token)) {
            log.error("获取微信Token失败, corpId={}, corpSecret={}, response={}", corpId, corpSecret, response);
        } else {
            log.info("获取微信企业版Token成功, token={}", token);
        }
        return this.accessToken = token;
    }

    public String createMenu(String menusToString, String agentId) {
        Request request = new Request();
        request.setUrl("https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token=" + getAccessToken() + "&agentid=" + agentId);
        request.setMethod(Request.POST);
        request.setRequestBody(menusToString.getBytes());
        Response response = request.execute();
        log.info("createMenu, response=" + (null == response ? response : response.toSimpleString()));
        return response.getBody();
    }

    public String getMenu(String agentId) {
        Request request = new Request();
        request.setUrl("https://qyapi.weixin.qq.com/cgi-bin/menu/get?access_token=" + getAccessToken() + "&agentid=" + agentId);
        request.setMethod(Request.GET);
        Response response = request.execute();
        log.info("getMenu, response=" + (null == response ? response : response.toSimpleString()));
        return response.getBody();
    }

    public String deleteMenu(String agentId) {
        Request request = new Request();
        request.setUrl("https://qyapi.weixin.qq.com/cgi-bin/menu/delete?access_token=" + getAccessToken() + "&agentid=" + agentId);
        request.setMethod(Request.GET);
        Response response = request.execute();
        log.info("deleteMenu, response=" + (null == response ? response : response.toSimpleString()));
        return response.getBody();
    }

    /**
     * @see org.budo.weixin.api.WeixinApi#sendMessage(org.budo.open.sdk.weixin.message.Message)
     */
    public String sendMessage(WeixinQiyeMessage weixinQiyeMessage) {
        if (null == weixinQiyeMessage) {
            log.error("weixinQiyeMessage is null");
            return "weixinQiyeMessage is null";
        }
        Request request = new Request();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + getAccessToken();
        request.setUrl(url);
        request.setMethod(Request.POST);
        request.setRequestBody(WeixinQiyeMessageUtil.toJson(weixinQiyeMessage).getBytes());
        Response response = request.execute();
        log.info("WeixinQiyeApi sendMessage To:{} Response：{}", url, response);
        if (NumberUtil.equals(200, response.getStatus())) {
            retryCount.remove(weixinQiyeMessage.getMessageId());
        } else {
            Integer count = retryCount.get(weixinQiyeMessage.getMessageId());
            count = (null == count ? 0 : count);
            if (count < 2) {
                retryCount.put(weixinQiyeMessage.getMessageId(), new Integer(count + 1));
                sendMessage(weixinQiyeMessage);
            } else {
                retryCount.remove(weixinQiyeMessage.getMessageId());
            }
        }
        String string = response.getBody();
        return string;
    }

    // {
    // "errcode": 0,
    // "errmsg": "ok",
    // "userid": "13699466308",
    // "name": "13699466308",
    // "department": [
    // 1
    // ],
    // "mobile": "13699466308",
    // "gender": "1",
    // "weixinid": "limingwei-_-",
    // "avatar": "http://shp.qpic.cn/bizmp/iammzOuGz5Pl8R6h2u2xMx1sTm0XGJeYfp2JoU6Yg2ibm8d9XRHztGXw/",
    // "status": 1,
    // "extattr": {
    // "attrs": []
    // }
    // }

    public Map<String, Object> getUserInfo(String userId) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=" + getAccessToken() + "&userid=" + userId;
        String response = HttpUtil.get(url).getBody();

        if (null == response || response.trim().isEmpty() || response.contains("no privilege to")) {
            throw new RuntimeException("no privilege to getUserInfo error, url=" + url + ", response=" + response);
        }

        log.info("getUserInfo(), url={}, response={}", url, response);
        return JSON.parseObject(response);
    }

    /**
     * @param departmentId
     * @return
     *         {
     *         "errcode": 0,
     *         "errmsg": "ok",
     *         "department": [
     *         {
     *         "id": 2,
     *         "name": "广州研发中心",
     *         "parentid": 1,
     *         "order": 10
     *         },
     *         {
     *         "id": 3
     *         "name": "邮箱产品部",
     *         "parentid": 2,
     *         "order": 40
     *         }
     *         ]
     *         }
     */
    public Map<String, Object> getDepartmentList(String departmentId) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=" + getAccessToken();
        if (null != departmentId) {
            url += "&id=" + departmentId;
        }
        String response = HttpUtil.get(url).getBody();
        log.info("getDepartmentList(), url={}, response={}", url, response);
        return JSON.parseObject(response);
    }

    /**
     * 获取部门成员详情
     * @param departmentId 部门ID
     * @param isFetchChild 是否递归获取子部门下面的成员
     * @return https://work.weixin.qq.com/api/doc#10063
     */
    public Map<String, Object> getUserInfoListByDepartmentId(String departmentId, Boolean isFetchChild) {
        String fetchChild = BooleanUtil.isTrue(isFetchChild) ? "1" : "0";
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=%s&department_id=%s&fetch_child=%s", getAccessToken(), departmentId, fetchChild);
        String response = HttpUtil.get(url).getBody();
        log.info("getUserInfoListByDepartmentId(), url={}, response={}", url, response);
        return JSON.parseObject(response);
    }

    /**
     * http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6
     * @see org.budo.weixin.api.WeixinApi#uploadMedia(String, Object)
     */
    public WeixinMediaUploadResult uploadMedia(String type, Object media) {
        Request request = new Request();
        request.setMethod(Request.POST);
        request.setUrl("https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=" + getAccessToken() + "&type=" + type);
        request.setField("media", media);
        Response response = request.execute();
        WeixinMediaUploadResult weixinMediaUploadResult = new WeixinMediaUploadResult(response.getBody());
        if (!weixinMediaUploadResult.getSuccess()) {
            log.error("uploadMedia failed, response={}, request={}", response, request);
        } else {
            log.info("uploadMedia success, response={}, request={}", response, request);
        }
        return weixinMediaUploadResult;
    }

    /**
     * 微信是跳转
     * @return 返回的是跳转地址
     */
    public String getMedia(String mediaId) {
        return "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=" + getAccessToken() + "&media_id=" + mediaId;
    }

    /**
     * 企业号二维码
     */
    public String getQiyeWeixinQrCode() {
        return null;
    }

    public Map<String, Object> getSnsToken(String appId, String appSecret, String code) {
        Request request = new Request();
        String access_token = getAccessToken();
        request.setUrl("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" + access_token + "&code=" + code);
        request.setMethod(Request.GET);
        Response response = request.execute();
        log.info("getSnsToken, response=" + (null == response ? response : response.toSimpleString()));

        String result = response.getBody();
        Map<String, Object> map = JSON.parseObject(result);
        String deviceId = StringUtil.toString(map.get("DeviceId"));
        if (StringUtil.isEmpty(deviceId)) {
            log.error("getSnsToken 失败, appId={}, appSecret={}, code={}, response={}", appId, appSecret, code, response);
        } else {
            log.info("获取企业微信deviceId成功, deviceId={}", deviceId);
        }
        return map;
    }
}